Ansibleのための YAML入門
渡辺です。
いよいよ今週末にDeveloersIO 2017が開催されます。 当日はAnsibleのハンズオンを担当しますので、参加予定の方はよろしくお願いします。 早速ですが、予習用の資料を用意しました(笑)
Ansibleでは、設定ファイルなどのフォーマットとしてYAMLを利用します。 本エントリーでは、Ansibleを利用する時に役立つYAMLフォーマットについて解説します。
データ構造フォーマット
YAMLはJSONに似た、データ定義のためのフォーマットです。 プログラミング言語とは異なり、ロジックを記述するフォーマットではありません。 アプリケーションでのデータシリアライズに利用されるケースが多く、Ansibleでは設定データの定義ファイルとして利用されます。
ハッシュ
ハッシュは、キー: 値
のデータ構造です。
プログラミング言語では、連想配列やMapなどと言われます。
キーとコロン(:)に続けて、対応する値を記述してください。 コロンの後に半角スペースをいれましょう。
db_user: master db_password: Pass1234 db_name: wp
YAMLでは、文字列をダブルクォート(")やシングルクォート(')で囲む必要はありません。 ですが、エディタのハイライト機能を活用するために、ダブルクォートやシングルクォートで囲むことも可能です。
db_user: "master" db_password: "Pass1234" db_name: "wp"
ただし、Ansibleで変数展開を行う時、ダブルクォートで囲む必要があります(後述)。
リスト
リストは複数のデータを格納するデータ構造です。 プログラミング言語でも同様にリストや配列などと言われます。
配列は行頭にハイフン(-)をつけてください。 また、ハイフンの後に半角スペースをいれましょう。
- common - mysql56-server - apache24
ハッシュのリスト
Ansibleで多く見かける構造は、ハッシュのリストです。 ハッシュのリストを定義するには、リストとするためにハイフンを使い、さらにインデントを揃えてハッシュのキーを列挙します。
- name: "Suzuka Nakamoto" metal_name: "SU-METAL" - name: "Yui Mizuno" metal_name: "YUI-METAL" - name: "kikuchi moa" metal_name: "MOA-METAL"
YAMLではインデントの位置によりデータ構造が決まります。 原則として、インデントは2文字の半角スペースで記述してください。 4文字でも認識しますが、可読性がイマイチです。
ハッシュのネスト
ハッシュはネストできます。 Ansibleでは、タスク定義でよく使われるフォーマットでしょう。
- name: apache24 installed yum: name: httpd24 - name: httpd service started service: name: httpd state: started enabled: yes
Ansibleの場合、タスクリストのキーがモジュール名に対応します。 モジュールのパラメータをネストしたハッシュとして定義してください。
最初のタスクでは、yumモジュールのname
パラメータにhttpd24を指定します。
次のタスクでは、serviceモジュールのname
パラメータにhttpdを、state
パラメータにstartedを、enabled
パラメータにyesを指定しています。
ここでもインデントが重要です。 インデントを間違えるとフォーマットエラーになったり、異なる構造と認識されたりします。
インデントを利用しないリストとハッシュ
YAMLではインデントを利用してデータ構造を記述します。 このため、行単位で変更を追いやすく、Gitなどのバージョン管理システムと相性が良いです。 しかし、YAMLでは、インライン記法(一行で書く記法)も用意されています。
空のリスト
空のリストはインライン記法で最も利用される状況です。
次のように[]
で記述します。
- hosts: wordpress-servers roles: []
なお、空のリストを記述したい場合、インデントを利用した記法は利用できません。
インラインのリスト
インラインのリストは、[]
の中に要素をカンマ区切りで列挙します。
- hosts: wordpress-servers roles: ["common", "mysql56-server"]
バージョン管理で差分を認識しにくいため、Ansibleではあまり利用しません。
インラインのハッシュ
インラインのハッシュは、{}
の中にキーと値をカンマ区切りで列挙します。
with_items: - { regexp: "^define\\('DB_NAME'.+$", replace: "define('DB_NAME', '{{ db_name }}');"} - { regexp: "^define\\('DB_USER'.+$", replace: "define('DB_USER', '{{ db_user }}');"}
この記述方法は、with_items
句などでハッシュを利用する場合によく使います。
この場合、行単位で意味があるため、バージョン管理での差分管理も問題ありません。
コメント
YAMLではコメントを記述できます。
# Playbook for wordpress - hosts: wordpress-servers roles: []
#
の後ろがコメントです。
YAMLドキュメントの先頭
Ansibleでは使うことがありませんが、YAMLではひとつのファイルに複数のYAMLを定義できます。
この時、---
で定義と定義の区切りを指定します。
Ansibleを利用する場合は、慣習として先頭に---
を記述することがあります。
--- # Playbook for wordpress - hosts: wordpress-servers roles: []
データ型
Ansibleを利用する場合、基本的にすべての値は文字列と考えて問題ありません。 しかし、YAMLを読み込む際にデータ型が影響するケースがあります。 注意したいのは数字だけで構成される文字列です。 YAMLとしては数値として扱われてしまうため、先頭のゼロが失われてしまうからです。
- name: "/etc/httpd/conf.d/wordpress.conf" template: src: wordpress.conf dest: /etc/httpd/conf.d/wordpress.conf owner: root group: root mode: "0644"
templateモジュールのmode
パラメータに0644
を設定してます。
ここでダブルクォートで囲まないと644
という数字として解釈されるでしょう。
モジュールで上手く処理していれば問題がありませんが、モジュールによってはエラーとなることがあります。
このため、数字のみで記述する場合、ダブルクォートで囲む方が良いでしょう。
Ansibleの変数展開
最後にAnsible特有の機能である変数展開についての解説です。 Ansibleでは変数を扱う機能があり、Playbookの一部を変数で置き換えます。
次のタスクでは、変数wp_path
をYAMLに展開します。
- name: "check {{ wp_path }}/wp-config.php' if exist" stat: path: "{{ wp_path }}/wp-config.php" register: stat_wp_config
変数を利用する場合、{{
と}}
で変数名を記述してください。
この時、必ずダブルクォートで全体を囲む必要があります。
次のようにダブルクォートがないと変数展開が行われないので注意してください。
- name: check {{ wp_path }}/wp-config.php' if exist stat: path: {{ wp_path }}/wp-config.php register: stat_wp_config
なお、変数名の前後に半角スペースは必須ではありません。 可読性向上のため、半角スペースを推奨します。
まとめ
YAMLフォーマットはデータ構造を直感的なインデントで表記します。 ネストした構造やインライン記法もあり、柔軟さもそなえています。 AWSでもCloudFormationやCodeXX系のサービスで使われるフォーマットなので、ポイントを抑えておきましょう。